#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <stdio.h>



#define _s_A  2
#define _s_B  0
#define _s_C  6
#define _s_D  4
#define _s_E  3
#define _s_F  1
#define _s_G  7
#define _s_dot 5

const unsigned char segs[] =
{
	_BV(_s_A) | _BV(_s_B) | _BV(_s_C) | _BV(_s_D) | _BV(_s_E) | _BV(_s_F),	//0
	_BV(_s_B) | _BV(_s_C),	//1
	_BV(_s_A) | _BV(_s_B) | _BV(_s_D) | _BV(_s_E) | _BV(_s_G),	//2
	_BV(_s_A) | _BV(_s_B) | _BV(_s_C) | _BV(_s_D) | _BV(_s_G),  //3
	_BV(_s_B) | _BV(_s_C) | _BV(_s_F) | _BV(_s_G),	//4
	_BV(_s_A) | _BV(_s_C) | _BV(_s_D) | _BV(_s_F) | _BV(_s_G), //5
	_BV(_s_A) | _BV(_s_C) | _BV(_s_D) | _BV(_s_E) | _BV(_s_F) | _BV(_s_G), //6
	_BV(_s_A) | _BV(_s_B) | _BV(_s_C), //7
	_BV(_s_A) | _BV(_s_B) | _BV(_s_C) | _BV(_s_D) | _BV(_s_E) | _BV(_s_F) | _BV(_s_G),//8
	_BV(_s_A) | _BV(_s_B) | _BV(_s_C) | _BV(_s_F) | _BV(_s_G),//9
	
	_BV(_s_A) | _BV(_s_B) | _BV(_s_C) | _BV(_s_E) | _BV(_s_F) | _BV(_s_G),	//A
	_BV(_s_C) | _BV(_s_D) | _BV(_s_E) | _BV(_s_F) | _BV(_s_G),	//B
	_BV(_s_A) | _BV(_s_D) | _BV(_s_E) | _BV(_s_F), //C
	_BV(_s_B) | _BV(_s_C) | _BV(_s_D) | _BV(_s_E) | _BV(_s_G), //D
	_BV(_s_A) | _BV(_s_D) | _BV(_s_E) | _BV(_s_F) | _BV(_s_G), //E
	_BV(_s_A) | _BV(_s_E) | _BV(_s_F) | _BV(_s_G) //F

};



#define _ms(n) (17*n)

void wait(unsigned int a)	//basic wait
{							
	volatile unsigned int b,c;
	for(b=0;b!= a; b++)for(c=0;c!= 50;c++);
	return;
}



unsigned char prescale=0;
unsigned char sec=0;
unsigned char min_1=0;
unsigned char min_10=0;
unsigned char hour_1=0;
unsigned char hour_10=0;
unsigned char show_t=0;


ISR(TIMER1_OVF_vect)
{
	if(++prescale == 225){prescale = 0;sec++;};
	if(sec>59){min_1++;sec=0;};
	if(min_1>9){min_1=0;min_10++;};
	if(min_10>5){min_10=0;hour_1++;};
	if(hour_1>9){hour_1=0;hour_10++;};
	if(hour_10>1 && hour_1>3){hour_1=0;hour_10=0;};
	
	if(++show_t==4) show_t=0;
	switch(show_t)
	{
		case 0:	//show minutes
			PORTC = 0x04;
			PORTD = (~segs[min_1]);
			break;
		case 1:	//show 10 minutes
			PORTC = 0x08;
			PORTD = (~segs[min_10]);
			break;
		case 2:	//show hours
			PORTC = 0x10;
			PORTD = (~segs[hour_1]) & ~_BV(_s_dot);
			break;
		case 3:	//show 10hours
			PORTC = 0x20;
			PORTD = (~segs[hour_10]);
			break;
		default:
			show_t = 0;
			break;
	}	
	return; 
}


#define B1() (bit_is_clear(PINB,3))
#define B2() (bit_is_clear(PINB,4))
#define B_WAIT 300

#define nop() asm volatile ("nop;")

int main(void)
{

	bool aa;
	TIMSK = 0x04;
	TCCR1B = 0x01;

	DDRD = 0xFF;
	DDRC = 0x3F;
	DDRB = 0x00;
	PORTB = 0xFF;
	
	sei();
	while(1)
	{
		if(B1())
		{
			wait(_ms(B_WAIT));
			min_1++;
			sec=0;
		}
		if(B2())
		{
			wait(_ms(B_WAIT));
			hour_1++;
			sec=0;
		}
	}
}
